/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	BRoleMgr.java
 * 模块说明：	
 * 修改历史：
 * 2006-8-30 - lxm - 创建。
 */
package com.hd123.rumba.user.biz;

import java.util.ArrayList;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Transaction;

import com.hd123.rumba.domain.CDomain;
import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.domain.biz.SDomain;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.gwt.base.client.biz.BPersistent;
import com.hd123.rumba.runtime.IManager;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.runtime.biz.BManager;
import com.hd123.rumba.user.CRole;
import com.hd123.rumba.user.CUser;
import com.hd123.rumba.user.IRole;
import com.hd123.rumba.user.IRoleMgr;
import com.hd123.rumba.user.IUser;
import com.hd123.rumba.user.IUserMgr;
import com.hd123.rumba.user.biz.share.BRoleMemberAgent;
import com.hd123.rumba.user.biz.share.BRoleShareAgent;
import com.hd123.rumba.user.biz.share.IBRoleMemberAgent;
import com.hd123.rumba.user.biz.share.IBRoleShareAgent;
import com.hd123.rumba.util.ClassifiedHashtable;

/**
 * 角色 | 业务层 | 管理员 | 实现类
 * 
 * @author lxm
 * 
 */
public class BRoleMgr extends BManager implements IBRoleMgr {

  public IManager getPerzMgr() throws BusinessException {
    return getRoleMgr();
  }

  public BRole createRole(String domainUuid) throws BusinessException, HibernateException {
    checkParameterNotNull(domainUuid, "domainUuid");
    BRole brole = new BRole();
    IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IDomain domain = domainMgr.getValidDomain(domainUuid);
    if (domain == null)
      throw new BusinessException("指定的" + CDomain.CAPTION_CLASS + "\"" + domainUuid
          + "\"找不到，或者不可用。");
    IRole prole = getRoleMgr().createRole(domain);
    brole.readFrom(prole);
    return brole;
  }

  public BRole loadRole(String uuid) throws BusinessException, HibernateException {
    checkParameterNotNull(uuid, "uuid");
    IRole prole = getRoleMgr().getRole(uuid);
    if (prole != null) {
      BRole brole = new BRole();
      brole.readFrom(prole);
      return brole;
    } else
      return null;
  }

  public List<SUser> loadRoleUsers(String roleUuid) throws BusinessException, HibernateException {
    checkParameterNotNull(roleUuid, "roleUuid");
    IRole prole = getRoleMgr().getRole(roleUuid);
    if (prole == null)
      return null;
    List plist = getRoleMgr().createUsersList(prole);
    List<SUser> list = new ArrayList();
    for (int i = 0; i < plist.size(); i++) {
      IUser puser = (IUser) plist.get(i);
      SUser user = new SUser();
      user.readFrom(puser);
      list.add(user);
    }
    return list;
  }

  public ClassifiedHashtable saveRoleT(BRole role, OperateContext operate)
      throws BusinessException, HibernateException {
    checkParameterNotNull(role, "role");
    checkParameterNotNull(operate, "operate");

    IDomainMgr dmMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IDomain domain = dmMgr.getDomain(role.getDomain().getUuid());
    IRole prole = null;
    if (role.getUuid() == null)
      prole = getRoleMgr().createRole(domain);
    else
      prole = getRoleMgr().getRole(role.getUuid());

    ClassifiedHashtable h = verifyToSave(role, prole, operate);
    if (h != null)
      return h;

    writeTo(role, prole);

    Transaction tx = getSession().beginTransaction();
    try {
      getRoleMgr().saveRole(prole, operate);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      throw new BusinessException(e);
    } finally {
      getSession().flush();
    }

    // 重新取出role。
    role.readFrom(prole);

    return null;
  }

  private ClassifiedHashtable verifyToSaveUsers(IRole prole, long roleOca)
      throws BusinessException, HibernateException {
    ClassifiedHashtable h = checkOca(prole, roleOca, CRole.CAPTION_CLASS, prole.getNameCode());
    if (h != null)
      return h;

    h = new ClassifiedHashtable();
    if (CRole.VALUE_STATE_DELETED.equals(prole.getState()))
      h.putMessage("state", ClassifiedHashtable.ERROR, "禁止修改" + CRole.CAPTION_STATE + "为 "
          + CRole.STATEMAP.get(prole.getState()) + " 的" + CRole.CAPTION_CLASS + "所"
          + CRole.CAPTION_USERS + "。");

    return h.size() > 0 ? h : null;
  }

  public ClassifiedHashtable saveRoleUsersT(String roleUuid, List<SUser> users,
      OperateContext operate, long roleOca) throws BusinessException, HibernateException {
    checkParameterNotNull(roleUuid, "roleUuid");
    checkParameterNotNull(users, "users");
    checkParameterNotNull(operate, "operate");

    IRole prole = getRoleMgr().getRole(roleUuid);
    ClassifiedHashtable h = verifyToSaveUsers(prole, roleOca);
    if (h != null)
      return h;

    boolean isRootAdmin = false;
    if (prole.getDomain().getUuid().equals(getDomainMgr().getRootDomain().getUuid())
        && CRole.VALUE_CODE_ROOT_ADMIN.equalsIgnoreCase(prole.getCode()))
      isRootAdmin = true;
    IUserMgr userMgr = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);

    Transaction tx = getSession().beginTransaction();
    try {
      // 从用户中删除角色
      List plist = getRoleMgr().createUsersList(prole);
      for (int i = 0; i < plist.size(); i++) {
        IUser puser = (IUser) plist.get(i);
        // root域admin用户，始终拥有admin角色。
        if (isRootAdmin && CUser.VALUE_LOGIN_ROOT_ADMIN.equalsIgnoreCase(puser.getLogin()))
          continue;
        boolean exists = false;
        for (int j = 0; j < users.size(); j++)
          if (users.get(j).getUuid().equals(puser.getUuid())) {
            exists = true;
            break;
          }
        if (!exists)
          userMgr.removeRoleFromUser(prole, puser, operate);
      }

      // 向用户添加角色
      plist = getRoleMgr().createUsersList(prole);
      for (int i = 0; i < users.size(); i++) {
        SUser user = users.get(i);
        boolean exists = false;
        for (int j = 0; j < plist.size(); j++) {
          IUser puser = (IUser) plist.get(j);
          if (user.getUuid().equals(puser.getUuid())) {
            exists = true;
            break;
          }
        }
        if (!exists) {
          IUser puser = userMgr.getUser(user.getUuid());
          userMgr.assignRoleToUser(prole, puser, operate);
        }
      }

      getRoleMgr().saveRole(prole, operate);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      throw new BusinessException(e);
    } finally {
      getSession().flush();
    }

    return null;
  }

  public void deleteRoleT(String roleUuid, OperateContext operate, long oca)
      throws BusinessException, HibernateException {
    checkParameterNotNull(roleUuid, "roleUuid");
    checkParameterNotNull(operate, "operate");

    IRole prole = getRoleMgr().getRole(roleUuid);
    if (prole == null)
      throw new BusinessException("找不到指定uuid(" + roleUuid + ")的" + CRole.CAPTION_CLASS + "。");
    ClassifiedHashtable h = verifyToDelete(prole, oca, operate);
    if (h != null)
      throw new BusinessException(h.getAllMessages());

    Transaction tx = getSession().beginTransaction();
    try {
      getRoleMgr().deleteRole(prole, operate);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      throw new BusinessException(e);
    } finally {
      getSession().flush();
    }
  }

  public void undeleteRoleT(String roleUuid, OperateContext operate, long oca)
      throws BusinessException, HibernateException {
    checkParameterNotNull(roleUuid, "roleUuid");
    checkParameterNotNull(operate, "operate");

    IRole prole = getRoleMgr().getRole(roleUuid);
    ClassifiedHashtable h = verifyToUndelete(prole, oca, operate);
    if (h != null)
      throw new BusinessException(h.getAllMessages());

    Transaction tx = getSession().beginTransaction();
    try {
      getRoleMgr().undeleteRole(prole, operate);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      throw new BusinessException(e);
    } finally {
      getSession().flush();
    }
  }

  public <T extends BPersistent> T getRole(String uuid, Class<T> bizClass) throws BusinessException,
      HibernateException {
    IRole prole = getRoleMgr().getRole(uuid);
    if (prole == null)
      return null;
    T brole = createBizClass2(bizClass);
    this.assignPerzToBiz(prole, brole);
    return brole;
  }

  public <T extends BPersistent> T getValidRole(String uuid, Class<T> bizClass) throws BusinessException,
      HibernateException {
    IRole prole = getRoleMgr().getValidRole(uuid);
    if (prole == null)
      return null;
    T brole = createBizClass2(bizClass);
    this.assignPerzToBiz(prole, brole);
    return brole;
  }

  public <T extends BPersistent> T getRoleByCode(String domainUuid, String code, Class<T> bizClass)
      throws BusinessException, HibernateException {
    checkParameterNotNull(domainUuid, "domainUuid");
    IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IDomain domain = domainMgr.getDomain(domainUuid);
    if (domain == null)
      throw new BusinessException("指定的" + CDomain.CAPTION_CLASS + "\"" + domainUuid + "\"找不到。");
    IRole prole = getRoleMgr().getRoleByCode(domain, code);
    if (prole == null)
      return null;
    T brole = createBizClass2(bizClass);
    this.assignPerzToBiz(prole, brole);
    return brole;
  }

  public List<BRole> getAllRoles(String domainUuid) throws BusinessException, HibernateException {
    checkParameterNotNull(domainUuid, "domainUuid");
    IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IDomain domain = domainMgr.getDomain(domainUuid);
    if (domain == null)
      throw new BusinessException("指定的" + CDomain.CAPTION_CLASS + "\"" + domainUuid + "\"找不到。");
    List plist = getRoleMgr().createAllRolesList(domain);
    List<BRole> list = new ArrayList();
    for (int i = 0; i < plist.size(); i++) {
      IRole prole = (IRole) plist.get(i);
      if (!CRole.VALUE_STATE_DELETED.equals(prole.getState())) {
        BRole role = new BRole();
        role.readFrom(prole);
        list.add(role);
      }
    }
    return list;
  }

  public IBPermAgent createRolePermAgent(String roleUuid) throws BusinessException {
    IBPermAgent agent = new BRolePermAgent();
    agent.setUserOrRoleUuid(roleUuid);
    return agent;
  }

  private IRoleMgr roleMgr = null;

  private IDomainMgr domainMgr = null;

  private IRoleMgr getRoleMgr() throws BusinessException {
    if (roleMgr == null)
      roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    return roleMgr;
  }

  private IDomainMgr getDomainMgr() throws BusinessException {
    if (domainMgr == null)
      domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    return domainMgr;
  }

  private ClassifiedHashtable verifyToSave(BRole role, IRole prole, OperateContext operate)
      throws BusinessException, HibernateException {
    ClassifiedHashtable h = this.checkOca(prole, role.getOca(), CRole.CAPTION_CLASS, prole
        .getNameCode());
    if (h != null)
      return h;

    h = new ClassifiedHashtable();

    if (role.getCode() == null)
      role.setCode("");
    else
      role.setCode(role.getCode().trim());
    if ("".equals(role.getCode()))
      h.putMessage("code", ClassifiedHashtable.ERROR, CRole.CAPTION_CLASS + "的"
          + CRole.CAPTION_CODE + "不能为空。");
    else {
      IRole prole2 = getRoleMgr().getRoleByCode(prole.getDomain(), role.getCode());
      if (prole2 != null && !prole2.getUuid().equals(role.getUuid()))
        h.putMessage("code", ClassifiedHashtable.ERROR, "已经存在相同" + CRole.CAPTION_CODE + "的"
            + CRole.CAPTION_CLASS + "。");
    }

    IDomain rootDomain = getDomainMgr().getRootDomain();
    if (prole.getDomain().getUuid().equals(rootDomain.getUuid())
        && CRole.VALUE_CODE_ROOT_ADMIN.equalsIgnoreCase(prole.getCode())) {
      if (!CRole.VALUE_CODE_ROOT_ADMIN.equalsIgnoreCase(role.getCode()))
        h.putMessage("code", ClassifiedHashtable.ERROR, "禁止修改" + CRole.CAPTION_CLASS + "\""
            + prole.getNameCode() + "@" + rootDomain.getNameCode() + "\"的" + CRole.CAPTION_CODE
            + "。");
    }
    if (CRole.VALUE_ROLETYPE_PUBLIC.equals(prole.getRoleType())
        && !prole.getDomain().equals(operate.getOperator().getDomain())) {
      h.putMessage("roleType", ClassifiedHashtable.ERROR, "不是当前组织(域)创建的"
          + CRole.CAPTION_ROLETYPE_PUBLIC + "，不允许修改。");
    }

    return h.size() > 0 ? h : null;
  }

  private void writeTo(BRole b, IRole p) throws BusinessException {
    p.setCode(b.getCode());
    p.setName(b.getName());
    p.setRoleType(b.getRoleType());
    p.setRemark(b.getRemark());
  }

  private ClassifiedHashtable verifyToDelete(IRole prole, long oca, OperateContext operate)
      throws BusinessException, HibernateException {
    ClassifiedHashtable h = this.checkOca(prole, oca, CRole.CAPTION_CLASS, prole.getNameCode());
    if (h != null)
      return h;

    h = new ClassifiedHashtable();
    if (CRole.VALUE_STATE_DELETED.equals(prole.getState()))
      h.putMessage("state", ClassifiedHashtable.WARN, "指定的" + CRole.CAPTION_CLASS + " "
          + prole.getNameCode() + " 已经是 " + CRole.CAPTION_STATE_DELETED + " 状态，没有必要再删除。");

    IDomain rootDomain = getDomainMgr().getRootDomain();
    if (prole.getDomain().getUuid().equals(rootDomain.getUuid())
        && CRole.VALUE_CODE_ROOT_ADMIN.equalsIgnoreCase(prole.getCode())) {
      h.putMessage("code", ClassifiedHashtable.ERROR, "禁止删除" + CRole.CAPTION_CLASS + "\""
          + prole.getNameCode() + "@" + rootDomain.getNameCode() + "\"。");
    }

    return h.size() > 0 ? h : null;
  }

  private ClassifiedHashtable verifyToUndelete(IRole prole, long oca, OperateContext operate)
      throws BusinessException, HibernateException {
    ClassifiedHashtable h = this.checkOca(prole, oca, CRole.CAPTION_CLASS, prole.getNameCode());
    if (h != null)
      return h;

    h = new ClassifiedHashtable();
    if (CRole.VALUE_STATE_NORMAL.equals(prole.getState()))
      h
          .putMessage("state", ClassifiedHashtable.WARN, "指定的" + CRole.CAPTION_CLASS + " "
              + prole.getNameCode() + " 已经是 " + CRole.STATEMAP.get(prole.getState())
              + " 状态，没有必要再恢复删除。");

    return h.size() > 0 ? h : null;
  }

  public IBRoleShareAgent createRoleShareAgent(String roleUuid) throws BusinessException {
    IBRoleShareAgent agent = new BRoleShareAgent();
    agent.setRoleUuid(roleUuid);
    return agent;
  }

  public IBRoleMemberAgent createRoleMemberAgent(String roleUuid) throws BusinessException {
    IBRoleMemberAgent agent = new BRoleMemberAgent();
    agent.setRoleUuid(roleUuid);
    return agent;
  }

  public List<SDomain> loadRoleShareDomains(String roleUuid) throws HibernateException,
      BusinessException {
    this.checkParameterNotNull(roleUuid, "roleUuid");
    IRole prole = getRoleMgr().getRole(roleUuid);
    if (prole == null)
      return null;
    List<IDomain> pdomains = getRoleMgr().createRoleShareDomains(prole);
    List<SDomain> domains = new ArrayList<SDomain>();
    for (int i = 0; i < pdomains.size(); i++) {
      SDomain d = new SDomain();
      d.readFrom(pdomains.get(i));
      domains.add(d);
    }
    return domains;
  }

}
